<template>
  <div class="pie-chart" :style="{ width: width + 'px', height: height + 'px' }">
    <div class="chart-header">
      <h3 class="chart-title">{{ title }}</h3>
    </div>
    <div class="chart-content">
      <svg :width="chartSize" :height="chartSize" class="chart-svg">
        <!-- 饼图扇形 -->
        <g v-for="(item, index) in pieData" :key="index">
          <path 
            :d="item.path" 
            :fill="item.color" 
            :stroke="'#fff'" 
            stroke-width="2"
            class="pie-slice"
            @mouseenter="onSliceHover(index)"
            @mouseleave="onSliceLeave"
          />
        </g>
        
        <!-- 中心圆 -->
        <circle 
          :cx="centerX" 
          :cy="centerY" 
          :r="centerRadius" 
          fill="white" 
          class="center-circle"
        />
        
        <!-- 标签 -->
        <text 
          v-for="(item, index) in pieData" 
          :key="'label-' + index"
          :x="item.labelX" 
          :y="item.labelY" 
          text-anchor="middle" 
          dominant-baseline="middle"
          class="slice-label"
          :class="{ 'label-visible': hoveredIndex === index }"
        >
          {{ item.name }}
        </text>
      </svg>
      
      <!-- 图例 -->
      <div class="legend">
        <div 
          v-for="(item, index) in pieData" 
          :key="'legend-' + index"
          class="legend-item"
          :class="{ 'legend-hovered': hoveredIndex === index }"
          @mouseenter="onSliceHover(index)"
          @mouseleave="onSliceLeave"
        >
          <div class="legend-color" :style="{ backgroundColor: item.color }"></div>
          <div class="legend-text">
            <span class="legend-name">{{ item.name }}</span>
            <span class="legend-value">{{ item.value }} ({{ item.percentage }}%)</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'

interface Props {
  width?: number
  height?: number
  title?: string
  data?: Array<{
    name: string
    value: number
    color?: string
  }>
}

const props = withDefaults(defineProps<Props>(), {
  width: 300,
  height: 300,
  title: '饼图',
  data: () => [
    { name: '类型A', value: 335, color: '#409EFF' },
    { name: '类型B', value: 310, color: '#67C23A' },
    { name: '类型C', value: 234, color: '#E6A23C' }
  ]
})

// 响应式数据
const hoveredIndex = ref<number | null>(null)

// 计算属性
const chartSize = computed(() => Math.max(100, Math.min(props.width, props.height) - 40))
const centerX = computed(() => chartSize.value / 2)
const centerY = computed(() => chartSize.value / 2)
const radius = computed(() => Math.max(20, (chartSize.value / 2) - 20))
const centerRadius = computed(() => Math.max(5, radius.value * 0.3))

const totalValue = computed(() => {
  return props.data.reduce((sum, item) => sum + item.value, 0)
})

const pieData = computed(() => {
  let currentAngle = -Math.PI / 2 // 从12点钟方向开始
  
  return props.data.map((item, index) => {
    const percentage = totalValue.value > 0 ? (item.value / totalValue.value) * 100 : 0
    const angle = totalValue.value > 0 ? (item.value / totalValue.value) * 2 * Math.PI : 0
    
    // 计算扇形路径
    const startAngle = currentAngle
    const endAngle = currentAngle + angle
    
    const x1 = centerX.value + radius.value * Math.cos(startAngle)
    const y1 = centerY.value + radius.value * Math.sin(startAngle)
    const x2 = centerX.value + radius.value * Math.cos(endAngle)
    const y2 = centerY.value + radius.value * Math.sin(endAngle)
    
    // 判断是否需要绘制大弧
    const largeArcFlag = angle > Math.PI ? 1 : 0
    
    const path = `M ${centerX.value} ${centerY.value} L ${x1} ${y1} A ${radius.value} ${radius.value} 0 ${largeArcFlag} 1 ${x2} ${y2} Z`
    
    // 计算标签位置
    const labelAngle = startAngle + angle / 2
    const labelRadius = radius.value * 0.7
    const labelX = centerX.value + labelRadius * Math.cos(labelAngle)
    const labelY = centerY.value + labelRadius * Math.sin(labelAngle)
    
    currentAngle = endAngle
    
    return {
      ...item,
      path,
      percentage: Math.round(percentage),
      labelX,
      labelY,
      color: item.color || getDefaultColor(index)
    }
  })
})

// 方法
const getDefaultColor = (index: number) => {
  const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#C0C4CC']
  return colors[index % colors.length]
}

const onSliceHover = (index: number) => {
  hoveredIndex.value = index
}

const onSliceLeave = () => {
  hoveredIndex.value = null
}
</script>

<style lang="scss" scoped>
.pie-chart {
  background: white;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  overflow: hidden;
  
  .chart-header {
    padding: 12px 16px;
    border-bottom: 1px solid #f0f0f0;
    
    .chart-title {
      margin: 0;
      font-size: 14px;
      font-weight: 500;
      color: #303133;
    }
  }
  
  .chart-content {
    // padding: 16px;
    display: flex;
    flex-direction: column;
    align-items: center;
    
    .chart-svg {
      .pie-slice {
        transition: all 0.3s ease;
        cursor: pointer;
        
        &:hover {
          transform: scale(1.05);
          transform-origin: center;
        }
      }
      
      .slice-label {
        font-size: 12px;
        font-weight: 500;
        fill: #303133;
        opacity: 0;
        transition: opacity 0.3s ease;
        
        &.label-visible {
          opacity: 1;
        }
      }
    }
    
    .legend {
      margin-top: 16px;
      width: 100%;
      
      .legend-item {
        display: flex;
        align-items: center;
        padding: 4px 0;
        cursor: pointer;
        transition: all 0.3s ease;
        
        &:hover,
        &.legend-hovered {
          background-color: #f5f7fa;
          border-radius: 4px;
          padding-left: 8px;
          padding-right: 8px;
        }
        
        .legend-color {
          width: 12px;
          height: 12px;
          border-radius: 2px;
          margin-right: 8px;
        }
        
        .legend-text {
          display: flex;
          flex-direction: column;
          
          .legend-name {
            font-size: 12px;
            color: #303133;
            font-weight: 500;
          }
          
          .legend-value {
            font-size: 11px;
            color: #909399;
          }
        }
      }
    }
  }
}
</style> 